import com.pojo.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
// 依赖注入方式：
//    1.  手动注入：
//            XML文件中的Bean标签的子标签Properties标签
//            XML文件中的Bean标签的子标签Constructor标签
//    2.   自动注入：
//            Autowired注解注入
//                Autowired 注解可以加在构造方法 普通方法或属性上  这样就不用显式创建set方法
//                  如果加在普通方法上也可以进行自动注入 而且不必满足bean的set方法限制 可以自定义方法名 可以有多个参数
//                  Spring首先在类里面扫描注入点（哪些属性或方法有Autowired注解）--->遍历所有的注入点--->
//                  是方法： 遍历里面的形参先byType再byName找到唯一的bean
//                  注意 扫描注入点也会遍历父类加了Autowired注解的方法 即使该父类没有Component修饰  然后判断方法或属性是否加了static
//                  如果加了static就不是一个注入点 然后看注解属性required值 是否为true（该属性或方法形参必须有值 没有注入会报错）
//                  之后就可以注入了：
//                              1. 属性注入点
//                                从spring中找到唯一的一个属性 通过反射注入 在这之前会扫描他是否有value注解
//                                如果有value注解 会解析里面的$进行占位符填充和# EL表达式
//                                如果没有value注解  会判断当前属性的类型是什么（比如是String Collection 数组 其他类的类型等等）：
//                                                  根据类型寻找自动装配的候选者 返回的是一个map
//                                                  因为对应同一个类型有可能找到多个bean对象 所以返回一个map
//                                                  如果自动装配的对象是一个集合 那么就把所有候选者都返回
//                                                  如果返回的map为空的 意味着没有找到候选者 会判断required注解是否是true 如果是true就抛出异常
//                                                  如果根据类型找 只找到了一个 直接返回这个bean
//                                                  如果根据类型找 找到了多个 那么就根据name筛选出一个bean 如果没有筛选出来还是判断required注解
//                                                  如何筛选：
//                                                    首先判断是否有Primary注解 有注解直接取有这个注解的候选者 如果没有就遍历候选者判断是否有Priority注解
//                                                      Priority注解 数字越小优先级越高
//                                                      如果都没有Primary注解 才根据name返回一个候选者
//                                                  byType--》得到候选者--》map  -->Primary-->Priority-->byName

//                              2. 方法注入点
//                                    同理
//                        通过以上分析 我们发现 其实依赖注入的变量名和Spring容器中的名字不必一致

//            Autowired--XML自动注入:
//                      构造方法：通过构造方法的参数类型来找bean
//                      byName:set 方法
//                      byType:获取到set方法中的唯一参数的参数类型，并且根据该类型去容器中获取bean
//                              如果找到多个，会报错。
//                  XML注入 可以通过构造方法set方法实现
//
//

public class Test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.test();


    }
}
